package com.mmall.service;

import com.google.common.collect.Lists;
import com.mmall.dao.SysAclMapper;
import com.mmall.dao.SysAclModuleMapper;
import com.mmall.dao.SysDeptMapper;
import com.mmall.dto.AclLevelDto;
import com.mmall.dto.AclModuleLevelDto;
import com.mmall.dto.DeptLevelDto;
import com.mmall.model.SysAcl;
import com.mmall.model.SysAclModule;
import com.mmall.model.SysDept;
import com.mmall.util.LevelUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 部门树的计算
 */
@Service
public class SysTreeService {
    @Resource
    private SysDeptMapper mapper;
    @Resource
    private SysAclModuleMapper aclModuleMapper;
    @Resource
    private SysCoreService sysCoreService;
    @Resource
    private SysAclMapper sysAclMapper;

    public Object userAclTree(Integer id) {
        List<SysAcl> userAcl = sysCoreService.getUserAclList(id);
        List<AclLevelDto> aclDtoList = Lists.newArrayList();

        for (SysAcl acl : userAcl){
            AclLevelDto aclLevelDto = AclLevelDto.adapt(acl);
            aclLevelDto.setChecked(true);
            aclLevelDto.setHasAcl(true);
            aclDtoList.add(aclLevelDto);
        }
        return aclListToTree(aclDtoList);
    }

    public List<AclModuleLevelDto> roleTree(int roleId) {
        // 1,当前用户已分配的权限点
        List<SysAcl> userAclList = sysCoreService.getCurrentUserAclList();
        // 2,当前角色分配的权限点
        List<SysAcl> roleAclList = sysCoreService.getRoleAclList(roleId);
        // 3,当前系统所有的权限点
        List<SysAcl> allAclList = sysAclMapper.getAll();

        //转换为set
        Set<Integer> userAclIdSet = userAclList.stream().map(sysAcl -> sysAcl.getId()).collect(Collectors.toSet());
        Set<Integer> roleAclIdSet = roleAclList.stream().map(sysAcl -> sysAcl.getId()).collect(Collectors.toSet());

        List<AclLevelDto> aclLevelDtoList = Lists.newArrayList();

        for (SysAcl acl : allAclList){
            AclLevelDto dto = AclLevelDto.adapt(acl);
            if (userAclIdSet.contains(dto.getId())){
                dto.setHasAcl(true);
            }
            if (roleAclIdSet.contains(acl.getId())){
                dto.setChecked(true);
            }
            aclLevelDtoList.add(dto);
        }

        return aclListToTree(aclLevelDtoList);
    }

    private List<AclModuleLevelDto> aclListToTree(List<AclLevelDto> aclLevelDtoList) {
        if (CollectionUtils.isEmpty(aclLevelDtoList)){
            return Lists.newArrayList();
        }
        List<AclModuleLevelDto> aclModuleLevelDtoList = aclModuleTree();
        Map<Integer,List<AclLevelDto>> moduleIdAclMap = aclLevelDtoList.stream().filter(dto->dto.getStatus() == 1).collect(Collectors.groupingBy(AclLevelDto::getAclModuleId));

        bindAclsWithOrder(aclModuleLevelDtoList,moduleIdAclMap);
        return aclModuleLevelDtoList;
    }

    /**
     * 将权限点和权限模块绑定
     * @param aclModuleLevelDtoList
     * @param moduleIdAclMap
     */
    private void bindAclsWithOrder(List<AclModuleLevelDto> aclModuleLevelDtoList, Map<Integer, List<AclLevelDto>> moduleIdAclMap) {
        if (CollectionUtils.isEmpty(aclModuleLevelDtoList)){
            return ;
        }
        for (AclModuleLevelDto aclModuleLevelDto : aclModuleLevelDtoList){
           List<AclLevelDto> dtos = moduleIdAclMap.get(aclModuleLevelDto.getId());
           if (CollectionUtils.isNotEmpty(dtos)){
              Collections.sort(dtos,aclSeqComparator);
              aclModuleLevelDto.setAclList(dtos);
           }
           bindAclsWithOrder(aclModuleLevelDto.getAclModuleList(),moduleIdAclMap);
       }
    }

    public List<DeptLevelDto> deptTree() {
        //获取所有的部门信息
        List<SysDept> deptList = mapper.getAllDept();
        List<DeptLevelDto> deptLevelDtoList = Lists.newArrayList();
        //将部门信息封装到dto中
        for (SysDept dept : deptList) {
            deptLevelDtoList.add(DeptLevelDto.adapt(dept));
        }
        //生成树
        return deptListToTree(deptLevelDtoList);
    }

    public List<AclModuleLevelDto> aclModuleTree() {
        List<SysAclModule> aclModules = aclModuleMapper.getAllAclModule();
        List<AclModuleLevelDto> aclModuleLevelDtos = Lists.newArrayList();

        for (SysAclModule aclModule : aclModules) {
            aclModuleLevelDtos.add(AclModuleLevelDto.adapt(aclModule));
        }

        return aclModuleListToTree(aclModuleLevelDtos);

    }

    private List<AclModuleLevelDto> aclModuleListToTree(List<AclModuleLevelDto> aclModuleLevelDtos) {
        if (CollectionUtils.isEmpty(aclModuleLevelDtos)) {
            return Lists.newArrayList();
        }

        Map<String, List<AclModuleLevelDto>> leveAclModuleMap = aclModuleLevelDtos.stream().collect(Collectors.groupingBy(AclModuleLevelDto::getLevel));

        List<AclModuleLevelDto> rootList = leveAclModuleMap.get(LevelUtil.ROOT);

        Collections.sort(rootList, aclModulsSeqComparator);

        transformAclModuleTree(rootList, LevelUtil.ROOT, leveAclModuleMap);

        return rootList;
    }

    private void transformAclModuleTree(List<AclModuleLevelDto> rootList, String level, Map<String, List<AclModuleLevelDto>> leveAclModuleMap) {

        for (int i = 0; i < rootList.size(); i++) {
            AclModuleLevelDto dto = rootList.get(i);

            String nextLevel = LevelUtil.calculateLevel(level, dto.getId());

            List<AclModuleLevelDto> dtos = leveAclModuleMap.get(nextLevel);

            if (CollectionUtils.isNotEmpty(dtos)) {

                Collections.sort(dtos, aclModulsSeqComparator);
                dto.setAclModuleList(dtos);

                transformAclModuleTree(dtos, nextLevel, leveAclModuleMap);
            }
        }
    }

    private List<DeptLevelDto> deptListToTree(List<DeptLevelDto> deptLevelDtoList) {
        if (CollectionUtils.isEmpty(deptLevelDtoList)) {
            //如果不存在，那么返回一个正常的list
            return Lists.newArrayList();
        }
        //根据层级分组
        Map<String, List<DeptLevelDto>> levelDeptMap = deptLevelDtoList.stream().collect(Collectors.groupingBy(DeptLevelDto::getLevel));
        //拿到根部门信息
        List<DeptLevelDto> rootList = levelDeptMap.get(LevelUtil.ROOT);
        //按照seq进行root部门的排序
        Collections.sort(rootList, deptSeqComparator);
        //获取下一层级
        transformDeptTree(rootList, LevelUtil.ROOT, levelDeptMap);

        return rootList;
    }

    private void transformDeptTree(List<DeptLevelDto> deptLevelDtoList, String level, Map<String, List<DeptLevelDto>> levelDeptMap) {
        for (int i = 0; i < deptLevelDtoList.size(); i++) {
            //遍历该层的每一个元素
            DeptLevelDto deptLevelDto = deptLevelDtoList.get(i);
            //处理当前层级的数据
            String nextLevel = LevelUtil.calculateLevel(level, deptLevelDto.getId());
            //处理下层
            List<DeptLevelDto> tempDeptList = levelDeptMap.get(nextLevel);

            if (CollectionUtils.isNotEmpty(tempDeptList)) {
                //排序
                Collections.sort(tempDeptList, deptSeqComparator);
                //设置下一层部门
                deptLevelDto.setDeptList(tempDeptList);
                //进入到下层处理
                transformDeptTree(tempDeptList, nextLevel, levelDeptMap);
            }

        }
    }

    private Comparator<DeptLevelDto> deptSeqComparator = new Comparator<DeptLevelDto>() {
        @Override
        public int compare(DeptLevelDto o1, DeptLevelDto o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };

    private Comparator<AclModuleLevelDto> aclModulsSeqComparator = new Comparator<AclModuleLevelDto>() {
        @Override
        public int compare(AclModuleLevelDto o1, AclModuleLevelDto o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };

    private Comparator<AclLevelDto> aclSeqComparator = new Comparator<AclLevelDto>() {
        @Override
        public int compare(AclLevelDto o1, AclLevelDto o2) {
            return o1.getSeq() - o2.getSeq();
        }
    };


}
